﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

using DashFire;
using UnityEngine;
using UnityEditor;

namespace DashFire.Assetbundle
{
  internal class ExportRes_ResList
  {
    static string s_ResVersionFilePath = "ResVersion_ab.txt";
    static string s_ResVersionFormat = "{0}	{1}	{2}	{3}	{4}	{5}	{6}";
    static string s_ResVersionHeader = "AssetBundleName	AssetName	AssetShortName	MD5	Size	Dependency	Version";

    //static string s_ResVersionClientFilePath = "ClientResVersion_ab.txt";
    //static string s_ResVersionClientFormat = "{0}	{1}	{2}	{3}	{4}	{5}";
    //static string s_ResVersionClientHeader = "AssetBundleName	AssetName	AssetShortName	MD5	Size	Dependency";

    internal static bool Export(bool isAppend = false)
    {
      Dictionary<string, ExportResInfo> tExportResDict = ExportConfig.s_ExportResDict;
      if (tExportResDict == null || tExportResDict.Count == 0) {
        ExportConfig.Log("ExportRes_ResList.Export tExportResDict is null or empty.");
        return false;
      }
      foreach (ExportResInfo data in tExportResDict.Values) {
        if (data.m_IsNeedBuild) {
          GenerateProperty(data);
        }
      }
      if (!OutputResVersionFile(isAppend)) {
        ExportConfig.Log("ExportRes_ResList.BuildResVersion OutputResVersionFile failed.");
        return false;
      }
      ExportConfig.Log("ExportRes_ResList.BuildResVersionFiles Success!");
      return true;
    }
    internal static bool LoadResVersion()
    {
      ClientResVersionProvider.Instance.Clear();
      string filePath = ExportConfig.GetFilePathAbs(
        string.Format("{0}/{1}", ExportConfig.GetPlatformPath(), s_ResVersionFilePath));
      if (!File.Exists(filePath)) {
        ExportConfig.Log("ExportRes_ResList.LoadResVersion not exist.");
        return true;
      }
      try {
        byte[] buffer = File.ReadAllBytes(filePath);
        bool ret = ClientResVersionProvider.Instance.CollectDataFromDBC(buffer);
        if (!ret) {
          ExportConfig.Log("ExportRes_ResList.LoadResVersion CollectDataFromDBC failed! filePath:" + filePath);
          return false;
        }
      } catch (System.Exception ex) {
        ExportConfig.Log("ExportRes_ResList.LoadResVersion failed! ex:" + ex);
        return false;
      }
      ExportConfig.Log("ExportRes_ResList.LoadResVersion Success");
      return true;
    }
    private static bool OutputResVersionFile(bool isAppend = false)
    {
      Dictionary<string, ExportResInfo> tExportResDict = ExportConfig.s_ExportResDict;

      if (isAppend) {
        if (!LoadResVersion()) {
          ExportConfig.Log("ExportRes_ResList.OutputResVersionFile LoadResVersion failed!");
        }
        foreach (ExportResInfo config in tExportResDict.Values) {
          if (config != null && config.m_IsNeedBuild) {
            ResVersionData data = new ResVersionData();
            data.m_AssetBundleName = config.m_PackageName;
            data.m_AssetName = config.m_AssetName;
            data.m_AssetShortName = config.m_AssetShortName;
            data.m_MD5 = config.m_MD5;
            data.m_Size = config.m_Size;
            data.m_Version = ExportConfig.s_Version;
            data.m_Dependency = FormatLoadDependency(config.m_LoadDependGuid);
            ClientResVersionProvider.Instance.AddData(data);
          }
        }
        string filePath = string.Format("{0}/{1}", ExportConfig.GetPlatformPath(), s_ResVersionFilePath);
        string fileContent = s_ResVersionHeader + "\n";
        foreach (ClientResVersionData data in ClientResVersionProvider.Instance.GetArray().Values) {
          if (data != null) {
            string dataStr = string.Format(s_ResVersionFormat + "\n",
              data.m_AssetBundleName, data.m_AssetName, data.m_AssetShortName,
              data.m_MD5, data.m_Size, data.m_Dependency, ExportConfig.s_Version);
            fileContent += dataStr;
          }
        }
        try {
          string dir = Path.GetDirectoryName(filePath);
          if (!Directory.Exists(dir)) {
            Directory.CreateDirectory(dir);
          }
          File.WriteAllText(filePath, fileContent, Encoding.UTF8);
        } catch (System.Exception ex) {
          ExportConfig.Log("ExportRes_ResList.OutputResVersionFile Save ClientResVersion failed!" + ex);
        }
      } else {
        string filePath = ResBuildHelper.FormatResListFilePath();
        string fileContent = s_ResVersionHeader + "\n";
        foreach (ExportResInfo config in tExportResDict.Values) {
          if (config != null && config.m_IsNeedBuild) {
            string abInfo = string.Format(s_ResVersionFormat + "\n",
              config.m_PackageName,
              config.m_AssetName,
              config.m_AssetShortName,
              config.m_MD5,
              config.m_Size,
              FormatLoadDependency(config.m_LoadDependGuid),
              ExportConfig.s_Version
              );
            fileContent += abInfo;
          }
        }
        try {
          string dir = Path.GetDirectoryName(filePath);
          if (!Directory.Exists(dir)) {
            Directory.CreateDirectory(dir);
          }
          File.WriteAllText(filePath, fileContent, Encoding.UTF8);
        } catch (System.Exception ex) {
          ExportConfig.Log("ExportRes_ResList.OutputResVersionFile failed!" + ex);
          return false;
        }
        AssetDatabase.Refresh();
      }
      ExportConfig.Log("ExportRes_ResList.OutputResVersionFile Success");
      return true;
    }
    private static bool GenerateProperty(ExportResInfo config)
    {
      string pathName = string.Format("{0}/{1}", ExportConfig.GetPlatformPath(), config.m_PackageName);
      string filePath = ExportConfig.GetFilePathAbs(pathName);
      if (File.Exists(filePath)) {
        config.m_MD5 = ResBuildHelper.GetFileMd5(filePath);
        config.m_Size = ResBuildHelper.GetFileSize(filePath);
      } else {
        ExportConfig.Log("ExportRes_ResList.GenerateProperty file not exist.filePath:" + filePath);
        config.m_MD5 = string.Empty;
        config.m_Size = 0;
      }
      return true;
    }
    private static string FormatLoadDependency(string dependencyList)
    {
      string ret = string.Empty;
      string[] dependency = dependencyList.Split(new string[] { ";", ":" }, StringSplitOptions.RemoveEmptyEntries);
      if (dependency != null && dependency.Length > 0) {
        foreach (string curDependGuid in dependency) {
          if (curDependGuid.StartsWith("ui_")) {
            ret += curDependGuid + ".ab" + ";";
          } else if (curDependGuid.Length > 2) {
            ret += string.Format("{0}/{1}.ab", curDependGuid.Substring(0, 2), curDependGuid) + ";";
          }
        }
      }
      return ret;
    }
  }
}
